;------------------------------------------------------------------------------
;
; As yet untitled
; The Calodox 1k ZX81 Intro
; Copyright (c) 2003 Sebastian Gerlach
;
; 1. Scroller
;
; Displays a huge scrolling text with shadow.
;
;------------------------------------------------------------------------------

.z80            ;use Z80 instruction set

org 4034h

htop	equ 17
hbot	equ 8

start_here:
	ld sp, 42feh
	ld ix, traceproc
	out (0feh), a
	
	ld hl, 4300h
	ld (hl), 0
	ld de, 4301h
	ld bc, 255
	ldir
	
loop_around:
modhere2:
	ld b, 2
waiter:
	ld hl, lflag
	ld (hl), 0
tag:
	bit 0, (hl)
	jr z, tag
	
	ld hl, drawproc
	ld a, 0ebh
	xor (hl)
modhere:	
	ld (hl), a
	
	djnz waiter
	
	ld a, (tcharoff)	; Load current bit offset
	or a				; Check if zero
	jr nz, charvalid	; If non zero, we still have some columns left
	
	; Reload a new character from ROM...
	
	ld hl, charcnt
	dec (hl)
	jr nz, keepup
	xor a
	ld (modhere), a
	inc a
	ld (modhere2+1), a
keepup:
	inc l
	dec (hl)
	jr nz, keepup2
	ld a, 28h
	ld (modns1), a
	ld a, 71
	ld (modns2+1), a
keepup2:

	
	ld hl, (stroff)		; hl points to next char in string	
	ld a, (hl)			; load char into a
	inc hl				; increment string pointer
	ld (stroff), hl		; store it again
	
	scf
	ld bc, stringend
	sbc hl, bc
	jp z, 4000h
	
	; a now contains char
	; Compute character offset in hl
	; We want hl=1e01h+8*a
	; a is between 00h and 3fh -> hl is between 1e01 and 1ff9h
	
	ld h, 0fh			; Will be 1e or 1f later
	rlca				; Rotate and clear carry (MSB is always 0)
	rla					; Rotate through carry
	rla					; Rotate through carry (highest bit of char is now in carry
	rl h				; Shift in carry to h (h is now 1e or 1f)
	ld l, a				; Keep rest in l
	inc l				; Skip first line of char
	
	ld de, tchar		; Load temp char address
	
	ld b, 6				; Copy 6 lines of character
loadcharline:
	ld a, (hl)			; 7 Load line
	ld c, a				; 4 Copy line
	rrca				; 4 Shift original line
	or c				; 4 Or them together (thickens char)
	ld (de), a			; 7 Store result
	inc e				; 4 Increment de
	inc l				; 4 Increment hl
	djnz loadcharline	; 13 Load next line
	
;	ld bc, 6			; 10 Copy 6 lines
;	ldir				; 21 Do the copy
	ld a, 8				; Set the remaining bit counter to 8
	ld (de), a			; Store it
	
charvalid:
	ld hl, tchar		; Address of temporary char
	ld b, 6				; Number of lines to copy
	ld de, 4308h		; Address of framebuffer
nextcharline:
	push bc
	push hl
	ld h, d				; Prepare for copy
	ld l, e
	inc l				; Source is one byte further (we scroll to the left...)
	ld bc, 39			; Shift over 31 chars
	ldir				; Copy them
	pop hl				; Get back temp char address
	
	xor a				; Clear a
	rlc (hl)			; Get bit into carry
	sbc 0				; Substract carry once (carry unchanged)
	sbc 0				; And again, now a is 0 or feh
	ld (de), a			; Load into frame buffer
	inc e				; Increment frame buffer pointer
	
	inc l				; Move onto next char line
	
	pop bc
	djnz nextcharline	; Continue until 6 lines out
	
	dec (hl)			; Decrement remaining bit count	

	jp loop_around 
	
tchar:		db 0,0,0,0,0,0
tcharoff:	db 0
stroff:		dw string
charcnt:	db 105			; Until speedup
charcnt2:	db 60			; Until shadow
	

lflag:	db 0

drawproc:
	ld r, a		; 0edh 04fh  / 006h 04fh
	ld b, 6
hr:	djnz hr
	ld b, htop
	ld c, 6
	ld ix, endofline
	ld a, 43h
	ld i, a
;	xor a
	ld a, 8
	
	; We have 50 frames per second
	; 314 scanlines per frame
	; 207 clocks per scanline
	; In all, 3249900 clocks per second
	; This is close enough to 3.25 MHz
	
nextline:
	jp oneline+8000h						; 10
oneline:	
	ld r,a									; 9
	db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0		; 64  16x4
	db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	    ; 64  16x4
	db 0,0,0,0,0,0,0,0
    jp ix									; 8
endofline:									; = 155

mod1:					; Modify for skewed mirrored text
	add 0				; Either add 0 (7) or nop nop (8)
	djnz nextline		; 13,8
	
						; = 202
						
	ld b, 13			; 7
lp: djnz lp				; 13, 8
mod2:					
	ld b, htop 			; 7 Character height (either htop or hbot)
	
	nop					; 4w
	ld d,(hl)			; 7w
mod3:
	add a, 40			; 7 Vidmem delta (+40 or -40)
	dec c				; 4
	jr nz, nextline		; 12,7		; 30
	
	ld b, 8			; 7
lp2: djnz lp2				; 13, 8
	ld hl, mod2+1
	ld a, hbot
	cp (hl)
modns1:
	jr finished		; originally 18h, then 28h (jr/jr z)
	ld (hl), a
	ld b, a
	ld a, 0
	ld (mod1), a
	ld a, -40
	ld (mod3+1), a
	ld a, -48
	ld c, 6
	jr nextline
	
finished:

	ld a, htop
	ld (mod2+1), a
	ld a, 40
	ld (mod3+1), a
	ld a, 0c6h
	ld (mod1), a
	ld ix, traceproc
modns2:
	ld a, 126		; originally 140, then 71
	ld hl, lflag
	ld (hl), 1		; Allow main loop to run
	jr doret

traceproc:
	in a, (0feh)
	ld b, 80
here:	djnz here
	
	ld ix, drawproc
	out (0ffh),a
	ld a, 71
doret:
	jp 029eh

string:
db 17h,17h,17h,00h,28h,26h,31h,34h
db 29h,34h,3dh,00h,35h,37h,2ah,38h
db 2ah,33h,39h,38h,00h,26h,00h,20h
db 30h,00h,2eh,33h,39h,37h,34h,00h
db 2bh,34h,37h,00h,38h,2eh,33h,28h
db 31h,26h,2eh,37h,00h,3fh,3dh,24h
db 1dh,00h,17h,17h,17h,00h,00h,00h
db 00h,00h,00h,15h,15h,00h,2ch,37h
db 2ah,2ah,39h,38h,00h,39h,34h,00h
db 3eh,3bh,2ah,38h,00h,26h,33h,29h
db 00h,26h,31h,31h,00h,34h,3ah,37h
db 00h,2bh,37h,2eh,2ah,33h,29h,38h
db 00h,15h,15h,00h,00h,00h,00h,00h
db 2ch,2ah,39h,00h,37h,2ah,26h,29h
db 3eh,00h,2bh,34h,37h,00h,31h,34h
db 26h,29h,2eh,33h,2ch,00h,33h,2ah
db 3dh,39h,00h,35h,26h,37h,39h,00h
db 16h,00h,3eh,2ah,26h,2dh,1ah,00h
db 3ch,2ah,00h,2dh,26h,3bh,2ah,00h
db 34h,33h,31h,3eh,00h,1dh,30h,00h
db 34h,2bh,00h,37h,26h,32h,00h,0eh
db 16h,11h

db 0,0,0,0,0,0,0,0,0
stringend:

end start_here
